package be.kul.osgi.ds.xmlstreamservice;


import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;


public class XMLStreamService
{

	private XStream xstream;
	
	public String getValue(String xml, String value){
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        InputSource is = new InputSource(new StringReader(xml));
			Document doc = builder.parse(is);
			 doc.getDocumentElement().normalize();	
			 NodeList nl = doc.getElementsByTagName(value);
			 Node node = nl.item(0);
			 return node.getTextContent();
		      //  Element root = (Element) doc.getElementsByTagName(tagname).getDocumentElement();
			//	return root.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return  null;
	}
	
	public String Sub(String xml, String value)  {

			try {
				XPathExpression expr = XPathFactory.newInstance().newXPath().compile("//" +value+"/*");
				InputSource inputSource = new InputSource(new ByteArrayInputStream(xml.getBytes()));
				NodeList nodeList = (NodeList) expr.evaluate(inputSource, XPathConstants.NODESET);
				StringWriter sw = new StringWriter();
				Transformer transformer = TransformerFactory.newInstance().newTransformer();
				transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
				transformer.transform(new DOMSource(nodeList.item(0)), new StreamResult(sw));
				return sw.toString();
			} catch (TransformerException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (XPathExpressionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}
	
	public ArrayList<String> getValues(String xml, String value){
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        InputSource is = new InputSource(new StringReader(xml));
			Document doc = builder.parse(is);
			 doc.getDocumentElement().normalize();	
			 NodeList nl = doc.getElementsByTagName(value);
			 int length = nl.getLength();
			 ArrayList<String> a = new ArrayList<String>();
			 for(int i=0;i<length;i++){
				 a.add(nl.item(i).getTextContent());
			 }

			 //Node node = nl..item(0);
			 return a;
		      //  Element root = (Element) doc.getElementsByTagName(tagname).getDocumentElement();
			//	return root.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return  null;
	}
	
	public String getRoot(URL xml) throws ParserConfigurationException, SAXException{
		DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
		try {
			Document doc = db.parse(new InputSource(xml.openStream()));
			 doc.getDocumentElement().normalize();	
			 Node node = doc.getDocumentElement();
			 String root = node.getNodeName();
			 return root;
		      //  Element root = (Element) doc.getElementsByTagName(tagname).getDocumentElement();
			//	return root.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return  null;
	}
	
	
	public String getRoot(String xml) throws ParserConfigurationException, SAXException{
   		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        InputSource is = new InputSource(new StringReader(xml));
			Document doc = builder.parse(is);
			 doc.getDocumentElement().normalize();	
			 Node node = doc.getDocumentElement();
			 String root = node.getNodeName();
			 root = root.replace(".Task", "");
			 return root;
		      //  Element root = (Element) doc.getElementsByTagName(tagname).getDocumentElement();
			//	return root.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return  null;
	}
	
	public String getRole(String xml) {
   		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        InputSource is = new InputSource(new StringReader("<Content>"+xml+"</Content>"));
			Document doc = builder.parse(is);
			 doc.getDocumentElement().normalize();	
			 Node node = doc.getElementsByTagName("Task").item(0).getFirstChild();
			 //Node node = doc.getDocumentElement().getFirstChild().getFirstChild().getFirstChild();
			 String root = node.getNodeName();
			 root = root.replace(".Task", "");
			 return root;
		      //  Element root = (Element) doc.getElementsByTagName(tagname).getDocumentElement();
			//	return root.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return  null;
	}
	
	public String getDue(String taskxml) throws ParserConfigurationException, SAXException{
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        InputSource is = new InputSource(new StringReader(taskxml));
			Document doc = builder.parse(is);
			 doc.getDocumentElement().normalize();	
			 NodeList nl = doc.getElementsByTagName("due");
			 Node node = nl.item(0);
			 return node.getTextContent();
		      //  Element root = (Element) doc.getElementsByTagName(tagname).getDocumentElement();
			//	return root.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return  null;
	}
	
	
	public XMLStreamService(){
		xstream = new XStream(new DomDriver());
	}
	
	public <T> T readClass(String xml, Class<T> clazz) {
		xstream.setClassLoader(clazz.getClassLoader());
		   return (T)xstream.fromXML(xml);
	}

	public Boolean export(Object o, String Path) {
		//xstream = new XStream(new DomDriver());
		//String xmlstring = xstream.toXML(o);
		//System.out.println(xmlstring);
	
		try {
			//path = C:\\LocalStorage
            FileOutputStream fs = new FileOutputStream(Path);
            //xstream.toXML(xmlstring, fs);
            xstream.toXML(o, fs);
            return true;
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
            return false;
        }
	}
	
	public String toXML(Object o) {
		//xstream = new XStream(new DomDriver());
		String xmlstring = xstream.toXML(o);
		//System.out.println(xmlstring);
		return xmlstring;
	}
	

	public <T> T readFile(String Path, Class<T> clazz) {
		xstream.setClassLoader(clazz.getClassLoader());
		try {
			FileInputStream fis = new FileInputStream(Path);
  			//System.out.println(xstream.fromXML(fis).toString());
			//return (T)xstream.fromXML(fis).toString();
			String s = xstream.fromXML(fis).toString();
			try {
				fis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(s);
			return readClass(s,clazz);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
		return null;
	}
	
	//is = new URL("http://google.com/").openStream();
	
	public <T> T readFile(URL url, Class<T> clazz) {
		xstream.setClassLoader(clazz.getClassLoader());
		InputStream fis;
		try {
			fis = url.openStream();
			return readClass(xstream.fromXML(fis).toString(),clazz);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println(xstream.fromXML(fis));
		//return (T)xstream.fromXML(fis).toString();
		 return null;
	}
	
}
